import ConfigParser
import getopt
import os
import logging,logging.config
import string
import sys

class Config:
    audit_config_file                = ''
    audit_parameters_list            = []
    database_type                    = 'mysql'
    database_name                    = ''
    database_host                    = 'localhost'
    database_user                    = ''
    database_password                = ''
    db_commit                        = 0
    log_level                        = logging.ERROR # only log errors by default
    logger                           = None
    logger_syslog                    = None
    logging_config                   = ''
    mysql_config_file                = ['/etc/mysql/my.cnf','/etc/my.cnf']
    mysql_base_dir                   = ''
    mysql_data_dir                   = ''
    mysql_log_dir                    = ''
    mysql_pid_file                   = ''
    mysql_socket_file                = ''
    
    
    def __dir_exists(self,f):
        d = os.path.dirname(f)
        if not os.path.exists(d):
            os.makedirs(d)


    def __init__(self):
        try:
            self.__parseArgs()
            self.__setupLogging()
        except Exception, exception:
            print "Error in reading/parsing configuration files - : %s" % str(exception).strip()
            sys.exit(1)


    def __readDBConfig(self,configfile):
        "Read  database config file"
        
        try:
            conf = ConfigParser.ConfigParser()
            conf.read(configfile)
            #Database parameters
            
            self.database_type = self.__confGet(conf, "database", "db_type") or self.database_type
            self.database_name = self.__confGet(conf, "database", "db_name") or self.database_name
            self.database_host = self.__confGet(conf, "database", "host") or self.database_host
            self.database_user = self.__confGet(conf, "database", "user") or self.database_user
            self.database_password = self.__confGet(conf, "database", "passwd") or self.database_password

            if self.__confGet(conf, "database", "commit"):
                if string.upper(self.__confGet(conf, "database", "commit"))[0] == 'Y':
                    self.db_commit = 1;
            
            
        except Exception, info:
            print "Error in retriving database configuration from 'db.conf' file. - %s" %info
            sys.exit(1)
            
    def __readConfig(self,configfile):
        """read mysql audit configuration"""
        
        try:
            self.audit_config_file = configfile
        
            conf = ConfigParser.ConfigParser()
            conf.read(configfile)
        
            # Log level
            self.log_level = self.__confGet(conf, "logging", "log_level") or self.log_level
            #logging configuration info.
            self.logging_config = self.__confGet(conf,"logging","logging_config_file") or self.logging_config
            if os.path.exists(self.logging_config)==False:
                print "It seems that the path of logging configuration file is not valid. Kindly re-check and try again."
                sys.exit(1)
            # read mysql audit test parameters
            for section in conf.sections():
                audit_dict={}
                if section.find("audit_")>=0:
                    audit_dict = self.__confGetSection(conf, section)
                    self.audit_parameters_list.append(audit_dict)
            #print self.audit_parameters_list
        except Exception,info:
                print "Error while reading mysql audit parameters information.- %s" %info
                sys.exit(1)
                
    def __confGetSection(self, conf, section):
        """returns the value of all the configuration options in one section or None if not set"""
        try:
            options = {}
            for i in conf.items(section):
                options [i[0]] = i[1]
            return options
        except ConfigParser.Error:
            return None # ignore missing values


    def __confGet(self, conf, section, option):
        """returns the value of the configuration option or None if not set"""
        try:
            return conf.get(section, option)
        except ConfigParser.Error:
            return None # ignore missing values


    def __setupLogging(self):
        try:
            "creates and returns file logger"
            logging.config.fileConfig(self.logging_config)
            self.logger = logging.getLogger('MySQL_Audit')
            try:
                self.logger.setLevel(int(self.log_level))
                #self.logger_syslog.setLevel(int(self.log_level))
            except:
                self.logger.warn("Bad value for option log_level: %s", self.log_level)
                #self.logger_syslog.warn("Bad value for option log_level: %s", self.log_level)
        except Exception, info:
            print "An error is encountered while setting up MySQL Audit logger - %s" %info
            sys.exit(1)

    def usage(self):
        "prints the command line options of the program"
        print """
                usage:""", os.path.basename(sys.argv[0]), """[options]

                options:
                -c file     read mysql audit configuration
                -d file     read database configuration
                -h          display this help
                -n          don't commit changes to the database
                -v          run in verbose mode
                --help      see -h
                --db_commit see -n
              """
                #-d db_file  read database config file
                #-l log_file read audit log files

    def __parseArgs(self):
        """parses the command line arguments"""
        try:
            opts, args = getopt.getopt(sys.argv[1:], "c:d:l:hn", ["help", "db_commit"])
        except getopt.GetoptError, exception:
            print "Error while parsing arguments %s -%s" % (args, str(exception).strip())
            self.usage()
            sys.exit(1)

        for opt, arg in opts:
            if opt == "-c":
                self.__readConfig(arg)
            elif opt == "-d":
                self.__readDBConfig(arg)
            elif opt == "-h" or opt == "--help":
                self.usage()
                sys.exit()
            elif opt == "-n" or opt == "--db_commit":
                self.db_commit = 1


    def setAction(self, act):
        "define and log what we are doing right now"
        self.logger.info(act)
        self.action = act[0].lower() + act[1:]


    def getAction(self):
        "return the last action"
        return self.action
